package com.yueya.auth.filter;

import com.yueya.auth.config.AuthProperties;
import com.yueya.auth.token.JwtToken;
import com.yueya.auth.utils.RequestUtil;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.yueya.auth.config.AuthConstant.TOKEN_NAME;

public class JwtFilter extends BasicHttpAuthenticationFilter {
    private AuthProperties authProperties;
    Logger logger= LoggerFactory.getLogger(getClass());
    @Override
    protected boolean isAccessAllowed(ServletRequest request,
                                      ServletResponse response, Object mappedValue) {
        try {
            executeLogin(request, response);
            return true;
        } catch (Exception e) {
            logger.info("jwt认证不通过", e);
            return false;
        }
    }

    @Override
    protected boolean executeLogin(ServletRequest request,
                                   ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader(TOKEN_NAME);
        String host = RequestUtil.getRemoteAddr(httpServletRequest);
        JwtToken jwtToken = new JwtToken(token,host);
        // 提交给realm进行登入，如果错误他会抛出异常并被捕获
        getSubject(request, response).login(jwtToken);
        // 如果没有抛出异常则代表登入成功，返回true
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse= (HttpServletResponse) response;
        if (authProperties.isJwtMode()) {
            RequestUtil.setHeader((HttpServletRequest) request,(HttpServletResponse) response);
        }
        httpServletResponse.setStatus(HttpStatus.METHOD_NOT_ALLOWED.value());
        return false;
    }

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        if (authProperties.isJwtMode()){
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
                RequestUtil.setHeader(httpRequest,httpResponse);
                return false;
            }
        }
        return super.preHandle(request,response);
    }

    public void setAuthProperties(AuthProperties authProperties) {
        this.authProperties = authProperties;
    }
}
